# -*- coding: utf-8 -*-
# @author : wanglei
# @date : 2020/3/31 21:07
# @description :
from manimlib.imports import *

# class AT(Scene):
#     def construct(self):
#         R1 = RegularPolygon(n=4,color=RED,fill_color=WHITE,fill_opacity=1.0)
#         R2=Circle(radius=1)
#         R2.move_to(7*RIGHT)
#
#         self.play(ClockwiseTransform(R1,R2),run_time=5)
#
#         self.wait()


# import random
# list1 = ['佛山', '南宁', '北海', '杭州', '南昌', '厦门', '温州']
# # 随机返回只有一个值的list
# a = random.sample(list1, 1)
#
# # 随机返回只有3个值的list
# b = random.sample(list1, 3)
# print(a)
# print(b)
# # 返回list


# l = (1,2,3)
#
# def test(*kw):
#     for k in kw:
#         print(k)
#
# test(*l)
#
# import math
# print(math.cos(math.radians(45))*math.cos(math.radians(45)))
#
#
# x = round(math.cos(math.radians(45))**2,2) - 0.5
# print('x', x)
# print(math.cos(math.radians(45)) * math.cos(math.radians(45)))
# print(math.cos(PI/4))

# class Test():
#     def __init__(self, *aa,flag=False):
#         if flag:
#             print(flag)
#             print(aa)
#         else:
#             print('test')
#
# Test(*['a','b'],flag=True)

class WriteConjecture(Scene):
    CONFIG = {
        "image_name": "ConjectureLineEquivalenceBigSphere",
        "q_coords": 1.28 * UP + 0.15 * LEFT,
        "circle_point_coords": 0.84 * RIGHT + 0.05 * DOWN,
        "tangent_point_coords": 0.85 * UP + 1.75 * LEFT,
        "plane_line_color": GOLD,
        "text_scale_factor": 0.75,
        "shift_plane_word_down": False,
        "include_image": False,
    }

    def construct(self):
        if self.include_image:
            image = ImageMobject(self.image_name)
            image.set_height(FRAME_HEIGHT)
            self.add(image)

        title = TextMobject("Conjecture:")
        title.to_corner(UR)

        cone_line = Line(self.q_coords, self.circle_point_coords)
        plane_line = Line(self.q_coords, self.tangent_point_coords)
        plane_line.set_color(self.plane_line_color)
        lines = VGroup(cone_line, plane_line)

        cone_line_words = TextMobject("Cone line")
        plane_line_words = TextMobject("Plane line")
        plane_line_words.set_color(self.plane_line_color)
        words = VGroup(cone_line_words, plane_line_words)

        for word in words:
            word.add_to_back(word.copy().set_stroke(BLACK, 5))
            word.in_equation = word.copy()

        equation = VGroup(
            TexMobject("||"),
            words[0].in_equation,
            TexMobject("||"),
            TexMobject("="),
            TexMobject("||"),
            words[1].in_equation,
            TexMobject("||"),
        )
        equation.arrange(RIGHT, buff=SMALL_BUFF)
        equation.scale(0.75)
        equation.next_to(title, DOWN, MED_LARGE_BUFF)
        equation.shift_onto_screen()
        title.next_to(equation, UP)

        for word, line in zip(words, lines):
            word.scale(self.text_scale_factor)
            word.next_to(ORIGIN, UP, SMALL_BUFF)
            if self.shift_plane_word_down and (word is plane_line_words):
                word.next_to(ORIGIN, DOWN, SMALL_BUFF)
            angle = line.get_angle()
            if abs(angle) > 90 * DEGREES:
                angle += PI
            word.rotate(angle, about_point=ORIGIN)
            word.shift(line.get_center())

        self.play(LaggedStartMap(
            FadeInFromDown,
            VGroup(title, equation),
            lag_ratio=0.7
        ))
        self.wait()
        for word, line in zip(words, lines):
            self.play(ShowCreation(line))
            self.play(WiggleOutThenIn(line))
            self.play(ReplacementTransform(
                word.in_equation.copy(), word
            ))
            self.wait()

class Text3D1(ThreeDScene):
    def construct(self):
        axes = ThreeDAxes()
        self.set_camera_orientation(phi=75 * DEGREES,theta=-45*DEGREES)
        text3d=TextMobject("This is a 3D text").scale(2)
        self.add(axes,text3d)


class Text3D2(ThreeDScene):
    def construct(self):
        axes = ThreeDAxes()
        self.set_camera_orientation(phi=75 * DEGREES,theta=-45*DEGREES)
        text3d=TextMobject("This is a 3D text").scale(2).set_shade_in_3d(True)
        text3d.rotate(PI/2,axis=RIGHT)
        self.add(axes,text3d)

# To see the text in the traditional form:
class Text3D3(ThreeDScene):
    def construct(self):
        axes = ThreeDAxes()
        self.set_camera_orientation(phi=75 * DEGREES,theta=-45*DEGREES)
        text3d=TextMobject("This is a 3D text")

        self.add_fixed_in_frame_mobjects(text3d) #<----- Add this
        text3d.to_corner(UL)

        self.add(axes)
        self.begin_ambient_camera_rotation()
        self.play(Write(text3d))

        sphere = ParametricSurface(
            lambda u, v: np.array([
                1.5*np.cos(u)*np.cos(v),
                1.5*np.cos(u)*np.sin(v),
                1.5*np.sin(u)
            ]),v_min=0,v_max=TAU,u_min=-PI/2,u_max=PI/2,checkerboard_colors=[RED_D, RED_E],
            resolution=(15, 32)).scale(2)

        self.play(ShowCreation(sphere))
        self.wait(2)


class CameraPosition3(ThreeDScene):

    def construct(self):
        config = {
                "dimension": 3,
                "x_min": 0,
                "x_max": 4,
                "y_min": 0,
                "y_max": 3,
                "z_axis_config": {},
                "z_min": 0,
                "z_max": 2,
                "z_normal": DOWN,
                "num_axis_pieces": 20,
            }
        axes = ThreeDAxes(**config)
        axes.x_axis.set_color(RED)
        axes.y_axis.set_color(GREEN)
        axes.z_axis.set_color(BLUE)

        self.set_camera_orientation(phi=60 * DEGREES, theta=1*DEGREES, distance=10)
        circle = Circle()
        x_axis_label = TexMobject('x')
        x_axis_label.rotate(PI / 2, axis=RIGHT)
        x_axis_label.rotate(PI / 2, axis=OUT)
        # self.add_fixed_in_frame_mobjects(x_axis_label)
        x_axis_label.move_to(axes.x_axis.get_end())
        y_axis_label = TexMobject('y')
        y_axis_label.rotate(PI / 2, axis=RIGHT)
        y_axis_label.rotate(PI / 2, axis=OUT)
        # self.add_fixed_in_frame_mobjects(y_axis_label)
        y_axis_label.move_to(axes.y_axis.get_end())
        z_axis_label = TexMobject('z')
        z_axis_label.rotate(PI / 2, axis=RIGHT)
        z_axis_label.rotate(PI / 2, axis=OUT)
        # self.add_fixed_in_frame_mobjects(z_axis_label)
        z_axis_label.move_to(axes.z_axis.get_end())
        axes.add(x_axis_label)
        axes.add(y_axis_label)
        axes.add(z_axis_label)
        self.play(ShowCreation(circle), ShowCreation(axes))
        self.wait()


class RotationsIn3d(ThreeDScene):
    def construct(self):
        self.set_camera_orientation(phi=80 * DEGREES, theta=-60 * DEGREES)

        def func():
            param = ParametricFunction(
                lambda u: np.array([
                    2 * u ** 2,
                    4 * u,
                    0
                ]), color=RED, t_min=0, t_max=1)
            return param
        curve1 = func()
        curve2 = curve1.copy()
        def update_curve(d,dt):
            d.rotate_about_origin(dt, RIGHT)
        curve2.add_updater(update_curve)
        axes = ThreeDAxes()
        self.add(curve1,curve2)
        self.add(axes)
        self.wait(2*PI)


class Example(ThreeDScene):
    def construct(self):
        axes=ThreeDAxes()
        self.add(axes)
        self.set_camera_orientation(phi=60 * DEGREES, theta=45 * DEGREES, distance=200)
        vector = Arrow(ORIGIN, end=2*RIGHT + 3*UP, color=RED, stroke_width=3, buff=0)
        self.play(Write(vector))

        # self.move_camera(phi=60*DEGREES,theta=45*DEGREES,run_time=6)
        # self.begin_ambient_camera_rotation(rate=0.2)
        self.wait()
        # self.stop_ambient_camera_rotation()


class write_formula(Scene):

    def construct(self):
        formula1 = TexMobject(
            r"\begin{cases} x=\rho\sin\varphi\cos\theta \\ y=\rho\sin\varphi\sin\theta \\ z=\rho\cos\varphi \\ \end{cases}")
        formula2 = TexMobject(
            r"\begin{cases} x=R\cos(u)+r\cos(u)\cos(v) \\ y=R\sin(u)+r\sin(u)\cos(v) \\ z=r\sin(v) \\ \end{cases}")
        formula3 = TexMobject(r"\begin{cases} x=u\cos(v) \\ y=u\sin(v) \\ z=u+v \\ \end{cases}")
        formula4 = TexMobject(
            r"\begin{cases} x=(1+\frac{v}{2}\cos(\frac{u}{2}))\cos(u) \\ y=(1+\frac{v}{2}\cos(\frac{u}{2}))\sin(u) \\ z=\frac{v}{2}\sin(\frac{u}{2}) \\ \end{cases}")
        formula5 = TexMobject(
            r"\begin{cases} x=(\cos(u)\cos(v))^3 \\ y=(\sin(u)\cos(v))^3 \\ z=(\sin(v))^3 \\ \end{cases}")
        formula6 = TexMobject(
            r"\begin{cases} x=(1-u)(4+\cos(v))\cos(\frac{\pi{u}}{2}) \\ y=(1-u)(4+\cos(v))\sin(\frac{\pi{u}}{2}) \\ z=4u+(1-u)\sin(v)+\pi \\ \end{cases}")
        formula7 = TexMobject(
            r"\begin{cases} x=\cos(u)\cos(v)\sin(v) \\ y=\sin(u)\cos(v)\sin(v) \\ z=\cos(u)\sin(u)(\cos(v))^2 \\ \end{cases}")

        self.play(Write(formula1), run_time=5)
        self.wait()
        self.play(ReplacementTransform(formula1, formula2), run_time=3)
        self.wait()
        self.play(ReplacementTransform(formula2, formula3), run_time=3)
        self.wait()
        self.play(ReplacementTransform(formula3, formula4), run_time=3, path_arc=3)
        self.wait()
        self.play(ReplacementTransform(formula4, formula5), run_time=3)
        self.wait()
        self.play(ReplacementTransform(formula5, formula6), run_time=3, path_arc=3)
        self.wait()
        self.play(ReplacementTransform(formula6, formula7), run_time=3)
        self.wait()


class PerceptronGradients(ThreeDScene):
    '''
    梯度
    '''
    captions=[

    ]

    def construct(self):
        config = {
            "dimension": 3,
            "x_min": -4,
            "x_max": 4,
            "y_min": -4,
            "y_max": 4,
            "z_axis_config": {},
            "z_min": -4,
            "z_max": 4,
            "z_normal": DOWN,
            "num_axis_pieces": 20,
        }
        axes = ThreeDAxes(**config)
        axes.x_axis.set_color(RED)
        axes.y_axis.set_color(GREEN)
        axes.z_axis.set_color(BLUE)

        x_axis_label = TexMobject('x')
        x_axis_label.rotate(PI / 2, axis=RIGHT)
        x_axis_label.rotate(PI / 2, axis=OUT)
        # self.add_fixed_in_frame_mobjects(x_axis_label)
        x_axis_label.move_to(axes.x_axis.get_end())
        y_axis_label = TexMobject('y')
        y_axis_label.rotate(PI / 2, axis=RIGHT)
        y_axis_label.rotate(PI / 2, axis=OUT)
        # self.add_fixed_in_frame_mobjects(y_axis_label)
        y_axis_label.move_to(axes.y_axis.get_end())
        z_axis_label = TexMobject('z')
        z_axis_label.rotate(PI / 2, axis=RIGHT)
        z_axis_label.rotate(PI / 2, axis=OUT)
        # self.add_fixed_in_frame_mobjects(z_axis_label)
        z_axis_label.move_to(axes.z_axis.get_end())
        axes.add(x_axis_label)
        axes.add(y_axis_label)
        axes.add(z_axis_label)
        self.add(axes)
        self.set_camera_orientation(phi=60 * DEGREES, theta=45 * DEGREES, distance=10)
        angle = math.degrees(math.atan(0.5 / 1.5)) * DEGREES
        print(angle)
        self.begin_ambient_camera_rotation(rate=0.4)
        arc = Arc(start_angle=0, angle=angle, radius=2, stroke_width=10, color=ORANGE)
        # arc.shift(np.array([2, 0.5, 0]))
        # arc.rotate(PI / 2, axis=RIGHT)
        arc.rotate(PI/2, axis=X_AXIS)
        self.play(Write(arc))
        self.wait(3)
        self.stop_ambient_camera_rotation()


class TestArc(GraphScene):
    def construct(self):
        arc = Arc(start_angle=0.35, angle=0.5, radius=2, stroke_width=10, color=ORANGE)
        # arc.shift(np.array([2, 0.5, 0]))
        # arc.rotate(PI / 2, axis=RIGHT)
        # arc.rotate(PI / 2, axis=OUT)
        self.play(Write(arc))